package com.nbcio.cd.interceptor;

import com.nbcio.cd.annotation.CdPermission;
import com.nbcio.cd.utils.CdPermissionUtils;
import com.nbcio.common.core.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 云网盘权限检查拦截器
 *
 * @author nbacheng
 * @date 2024-01-01
 */
@Component
public class CdPermissionInterceptor implements HandlerInterceptor {

    @Autowired
    private CdPermissionUtils permissionUtils;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        // 检查方法上的权限注解
        CdPermission methodAnnotation = method.getAnnotation(CdPermission.class);
        if (methodAnnotation != null) {
            checkPermission(methodAnnotation, request);
        }

        // 检查类上的权限注解
        CdPermission classAnnotation = method.getDeclaringClass().getAnnotation(CdPermission.class);
        if (classAnnotation != null) {
            checkPermission(classAnnotation, request);
        }

        return true;
    }

    /**
     * 检查权限
     */
    private void checkPermission(CdPermission annotation, HttpServletRequest request) {
        String resourceType = annotation.resourceType();
        String permissionType = annotation.permissionType();
        String paramName = annotation.paramName();
        String message = annotation.message();

        if (resourceType.isEmpty() || permissionType.isEmpty()) {
            return;
        }

        // 从请求参数中获取资源ID
        Long resourceId = getResourceIdFromRequest(request, paramName);
        if (resourceId == null) {
            throw new ServiceException("无法获取资源ID");
        }

        // 检查权限
        boolean hasPermission = false;
        if ("file".equals(resourceType)) {
            hasPermission = permissionUtils.checkFilePermission(resourceId, permissionType);
        } else if ("folder".equals(resourceType)) {
            hasPermission = permissionUtils.checkFolderPermission(resourceId, permissionType);
        }

        if (!hasPermission) {
            throw new ServiceException(message);
        }
    }

    /**
     * 从请求中获取资源ID
     */
    private Long getResourceIdFromRequest(HttpServletRequest request, String paramName) {
        String paramValue = null;

        // 从路径参数中获取
        if (paramName.isEmpty()) {
            // 尝试从URL路径中提取ID
            String pathInfo = request.getPathInfo();
            if (pathInfo != null) {
                String[] pathSegments = pathInfo.split("/");
                for (String segment : pathSegments) {
                    try {
                        return Long.parseLong(segment);
                    } catch (NumberFormatException e) {
                        // 继续尝试下一个段
                    }
                }
            }
        } else {
            // 从请求参数中获取
            paramValue = request.getParameter(paramName);
        }

        if (paramValue != null) {
            try {
                return Long.parseLong(paramValue);
            } catch (NumberFormatException e) {
                throw new ServiceException("无效的资源ID: " + paramValue);
            }
        }

        return null;
    }
}
